/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package post;

import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Stephen
 */
public class Client {

    private ProductCatalog catalog;
    private Vector<Transaction> completedTransactions;
    private Vector<TransactionItem> cart;
    private ServerRMI stub;

    public Client() {
        completedTransactions = new Vector<Transaction>();
        cart = new Vector<TransactionItem>();
    }

    /**
     * This method connects to the server and grabs a local copy of the ProductCatalog
     */
    public void init() {
        try {
            Registry registry = LocateRegistry.getRegistry();
            stub = (ServerRMI) registry.lookup("ServerRMI");
            updateCatalog();
        } catch (Exception e) {
            System.err.println("Client exception: " + e.toString());
            e.printStackTrace();
            System.exit(1);
        }
    }
    
    /**
     * This method pulls a new copy of the ProductCatalog from the server
     */
    public void updateCatalog() {
        try {
            catalog = stub.getProductCatalog();
        } catch (RemoteException ex) {
            Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * This method adds another TransactionItem to the cart
     * @param upc is the UPC of the item to add 
     * @param quantity is the quantity of items to add
     */
    public void addItemToCart(String upc, int quantity) {
        cart.add(new TransactionItem(upc, quantity));
    }

    /**
     * This method returns the current total price of items in the cart.
     * @return a float with the value of the current total price
     */
    public float getTotal() {
        float total = 0.F;
        for (int i = 0; i < cart.size(); i++) {
            total += (cart.elementAt(i).getQuantity() * catalog.getPriceByUpc(cart.elementAt(i).getUpc()));
        }
        return total;
    }

    /**
     * This method is for completing a transaction.  The transaction is sent to the server to be added to a
     * transaction log.
     * @param customerName is the name of the customer
     * @param payment is the payment type
     * @param amountReceived is the amount received.  Enter 0 if not cash payment.
     * @param cardNum is the credit card number.  Enter 0 if not a credit payment.
     * @return is a string containing the invoice
     */
    public String checkOut(String customerName, Payment payment, float amountReceived, int cardNum) {
        int numItems = cart.size();
        TransactionItem[] transItems = cartToArray();
        Date date = new Date();
        Transaction curTransaction = new Transaction(customerName, transItems, payment, date, numItems, amountReceived, cardNum);
        completedTransactions.add(curTransaction);
        try {
            stub.addTransactions(curTransaction);
        } catch (RemoteException ex) {
            Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
        }

        //Printing Invoice
        float total = 0.F;
        SimpleDateFormat date_format = new SimpleDateFormat("MMM dd,yyyy HH:mm");
        String invoice = "Fake Store" + "\r\n\r\n" + customerName + "   " + date_format.format(date) + "\r\n";

        for (int i = 0; i < numItems; i++) {
            invoice += "Item: ";

            for (Product ps : catalog.toArray()) {
                if (transItems[i].getUpc().equals(ps.getUpc())) {
                    invoice += ps.getDescription() + "  " + transItems[i].getQuantity() + "  " + ps.getPrice() + "  " + String.valueOf(ps.getPrice() * transItems[i].getQuantity());
                    total += (ps.getPrice()) * (transItems[i].getQuantity());

                    break;
                }

            }
            invoice += "\r\n";
        }

        invoice += "------\r\n";
        String payTypeInfo = new String();
        if (payment == Payment.Cash) {
            payTypeInfo = "\nAmount Tendered: $" + amountReceived + " \tChange: $" + (amountReceived - total);
        }
        if (payment == Payment.CreditCard) {
            payTypeInfo = "\nCard Number : " + cardNum;
        }
        invoice += "Total: $" + total + " Paid by " + payment.name() + payTypeInfo;
        cart = new Vector<TransactionItem>();
        return invoice;
    }

    /**
     * This method returns a String array with all UPCs of all items in the catalog.
     * @return is the array containing the UPCs
     */
    public String[] getAllUPC() {
        return catalog.getAllUPC();
    }

    /**
     * This method gets the price of a product
     * @param upc is the UPC of the product
     * @return is the price of the product
     */
    public float getPriceByUPC(String upc) {
        return catalog.getPriceByUpc(upc);
    }

    /**
     * This method gets the description of a product
     * @param upc is the UPC of the product
     * @return is the description of the product
     */
    public String getDescByUPC(String upc) {
        return catalog.getDescByUpc(upc);
    }
    
    /**
     * This method is used to get the number of different products in the cart
     * @return is the number of different products in the cart
     */
    public int getNumItemsInCart() {
        return cart.size();
    }
    
    /**
     * This method gets information about a product in the cart
     * @param num is the nth item in the cart. (zero indexed)
     * @return is a string array containing information about the product in
     * the cart.  the 0th element is the UPC, and the 1st element is the
     * quantity.
     */
    public String[] getItemInCart(int num) {
        if (num < cart.size()) {
            String[] itemInfo = new String[2];
            itemInfo[0] = cart.elementAt(num).getUpc();
            itemInfo[1] = Integer.toString(cart.elementAt(num).getQuantity());
            return itemInfo;
        }
        else {
            return null;
        }
    }

    private TransactionItem[] cartToArray() {
        int size = cart.size();
        TransactionItem[] transItems = new TransactionItem[size];
        for (int i = 0; i < size; i++) {
            transItems[i] = cart.elementAt(i);
        }
        return transItems;
    }
}
